<template>
  <div class="page-container">
    <div class="page-content">
      <el-row :gutter="10">
        <el-col :span="6">
          <div class="panel-container no-margin dept-list-box">
            <div class="dept-list">
              <el-tree
                ref="tree1"
                :data="deptList"
                :props="defaultProps"
                lazy
                :load="loadNode"
                node-key="id"
                @node-click="handleNodeClick"
              />
            </div>
            <div class="left-line">
              <i
                class="el-icon-circle-plus-outline icon"
                @click="handleAddDept"
              />
            </div>
          </div>
        </el-col>
        <el-col :span="18">
          <div class="panel-container no-margin dept-detail-box">
            <div class="panel-title">
              基本信息-{{ editModel === 'add' ? '新增' : '编辑' }}
            </div>
            <el-form
              ref="form"
              :rules="rules"
              :model="form"
              label-width="100px"
            >
              <el-form-item
                prop="name"
                label="部门名称:"
              >
                <el-input
                  v-model="form.name"
                  style="width: 193px"
                  :disabled="editModel === 'edit' && currentData.level === 0"
                  maxlength="20"
                />
              </el-form-item>
              <el-form-item
                prop="parent_name"
                label="上级部门:"
              >
                <el-select
                  ref="selectTree"
                  v-model="form.parent_name"
                  placeholder="请选择"
                  :disabled="editModel === 'edit' && currentData.level === 0"
                >
                  <el-option
                    :key="form.parent_id"
                    :value="form.parent_id"
                    :label="form.parent_name"
                    hidden
                  />
                  <el-tree
                    ref="tree2"
                    :data="deptSelectList"
                    :props="defaultProps"
                    highlight-current
                    node-key="id"
                    @node-click="handleFatherClick"
                  />
                </el-select>
              </el-form-item>
              <el-form-item
                prop="status"
                label="是否启用:"
              >
                <el-radio-group
                  v-model="form.status"
                  :disabled="editModel === 'edit' && currentData.level === 0"
                >
                  <el-radio :label="1">启用</el-radio>
                  <el-radio :label="0">停用</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item
                v-if="editModel === 'edit'"
                label=""
              >
                <div class="text-tip">
                  最新修改时间：{{ currentData.update_time }}
                </div>
              </el-form-item>
              <el-form-item style="margin-bottom: 0; margin-top: 40px">
                <el-button
                  v-if="editModel === 'edit'"
                  :disabled="editModel === 'edit' && currentData.level === 0"
                  @click="handleDelete"
                >
                  删除
                </el-button>
                <el-button
                  :loading="loading"
                  type="primary"
                  :disabled="editModel === 'edit' && currentData.level === 0"
                  @click="handleSubmit"
                >
                  保存
                </el-button>
              </el-form-item>
            </el-form>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import {
  apiSysDeptList,
  apiSysDeptAdd,
  apiSysDeptEdit,
  apiSysDeptDel,
  apiSysDeptSelect
} from '@/api/system'
import { formatDate } from '@/utils'

export default {
  name: 'Department',
  components: {},
  data() {
    const validaName = (rule, value, callback) => {
      this.hasRepeatName(value, this.deptSelectList)
      if (this.repeatName) {
        this.repeatName = false
        callback(new Error('部门名称不能重复'))
      } else {
        callback()
      }
    }
    const validaParentId = (rule, value, callback) => {
      if (this.form.id === this.form.parent_id) {
        callback(new Error('不能选择当前部门为上级部门'))
      } else {
        callback()
      }
    }
    return {
      deptList: [],
      deptSelectList: [],
      defaultProps: {
        children: 'children',
        label: 'name',
        isLeaf: function (data, node) {
          return data.is_have_child === 0
        }
      },
      form: {
        name: '',
        parent_name: '',
        parent_id: '',
        status: 1
      },
      rules: {
        name: [
          { required: true, message: '请输入部门名称', trigger: 'blur' },
          { validator: validaName, trigger: 'blur' }
        ],
        parent_name: [
          { required: true, message: '请选择上级部门', trigger: 'blur' },
          { validator: validaParentId, trigger: 'blur' }
        ]
      },
      loading: false,
      editModel: 'add',
      parentNode: null,
      currentData: {},
      repeatName: false,
      oldParentId: ''
    }
  },
  mounted() {
    this.getDeptSelect()
  },
  methods: {
    getDeptSelect() {
      apiSysDeptSelect().then((res) => {
        this.deptSelectList = res.data
      })
    },
    // 获取数据
    loadNode(node, resolve) {
      const { level } = node
      let id = node.data.id
      if (level === 0) {
        id = ''
      }
      apiSysDeptList({ id }).then((res) => {
        resolve(res.data)
      })
    },
    // 选择部门
    handleNodeClick(data) {
      this.editModel = 'edit'
      this.currentData = data
      this.parentNode = this.$refs.tree1.getNode(data.parent_id)
      this.form = {
        id: data.id,
        name: data.name,
        parent_name: this.parentNode?.data?.name,
        parent_id: data.parent_id,
        status: data.status
      }
      this.oldParentId = data.parent_id
    },
    // 添加部门
    handleAddDept() {
      this.resetForm()
      this.editModel = 'add'
    },
    // 选择上级部门
    handleFatherClick(data) {
      this.parentNode = this.$refs.tree2.getNode(data.id)
      this.form.parent_id = data.id
      this.form.parent_name = data.name
      this.$refs.selectTree.blur()
    },
    // 删除
    handleDelete() {
      if (this.currentData.is_have_child !== 0) {
        this.$message.error(this.currentData.name + '有下级部门，不能删除')
        return
      }
      this.$confirm('确定要删除' + this.currentData.name + '?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.loading = true
        apiSysDeptDel({ id: this.form.id })
          .then((res) => {
            this.loading = false
            this.$message({
              message: '删除成功',
              type: 'success'
            })
            this.updateTree({ type: 'delete', id: this.form.id })
            this.resetForm()
            this.editModel = 'add'
          })
          .catch((res) => {
            this.loading = false
          })
      })
    },
    // 提交
    handleSubmit() {
      this.$refs.form.validate((valid, message) => {
        if (valid) {
          this.loading = true
          if (this.editModel === 'add') {
            apiSysDeptAdd(this.form)
              .then((res) => {
                this.loading = false
                this.$message({
                  message: '保存成功',
                  type: 'success'
                })
                const newDate = {
                  id: res.data.id,
                  is_have_child: 0,
                  level: this.parentNode.level + 1,
                  name: this.form.name,
                  parent_id: this.form.parent_id,
                  status: this.form.status,
                  update_time: formatDate()
                }
                this.updateTree({
                  type: 'add',
                  data: newDate,
                  parentId: this.form.parent_id
                })
                this.resetForm()
                this.editModel = 'add'
              })
              .catch((res) => {
                this.loading = false
              })
          } else {
            apiSysDeptEdit(this.form)
              .then((res) => {
                this.loading = false
                this.$message({
                  message: '保存成功',
                  type: 'success'
                })
                const newDate = {
                  id: this.form.id,
                  is_have_child: this.currentData.is_have_child,
                  level: this.parentNode.level + 1,
                  name: this.form.name,
                  parent_id: this.form.parent_id,
                  status: this.form.status,
                  update_time: formatDate()
                }
                this.setStatus(this.form.id, this.form.status)
                this.updateTree({
                  type: 'edit',
                  id: this.form.id,
                  data: newDate,
                  parentId: this.form.parent_id
                })
                this.resetForm()
                this.editModel = 'add'
              })
              .catch((res) => {
                this.loading = false
              })
          }
        }
      })
    },
    // 设置当前部门子部门的启用状态
    setStatus(id, status) {
      if (!id) {
        return
      }
      const node = this.$refs.tree1.getNode(id)
      if (!node) {
        return
      }
      const newDate = node.data
      newDate.status = status
      node.data = newDate
      const children = node.childNodes
      if (!children) {
        return
      }
      children.forEach((item) => {
        this.setStatus(item.data.id, status)
      })
    },
    updateTree({ type, id, data, parentId }) {
      if (type === 'add') {
        this.$refs.tree1.append(data, parentId)
      } else if (type === 'edit') {
        // 更新,删除原节点，parentid追加节点
        if (this.$refs.tree1.getNode(id)) {
          this.$refs.tree1.getNode(id).data = data
        }
        if (parentId !== this.oldParentId) {
          this.$refs.tree1.remove(id)
          this.$refs.tree1.append(data, parentId)
          const newParent = this.$refs.tree1.getNode(parentId)
          newParent.isLeaf = false
        }
      } else if (type === 'delete') {
        // 删除原节点
        this.$refs.tree1.remove(id)
      }
      this.getDeptSelect()
    },
    // 重置表单
    resetForm() {
      this.getDeptSelect()
      this.form.id = this.form.parent_id = ''
      this.$refs.form.resetFields()
    },
    // 名称重复
    hasRepeatName(value, node) {
      if (!value || !node) {
        return
      }
      node.forEach((item) => {
        if (item.name === value && item.id !== this.currentData.id) {
          this.repeatName = true
        } else if (item.children) {
          this.hasRepeatName(value, item.children)
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.left-line {
  position: absolute;
  top: 12px;
  right: 16px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  .icon {
    font-size: 20px;
    flex-shrink: 0;
    margin-left: 10px;
    color: #5db42c;
    cursor: pointer;
    &:hover {
      opacity: 0.8;
    }
  }
}
.label-list {
  margin-top: 12px;
  border: 1px solid #eee;
  padding: 12px;
  line-height: 40px;
  font-size: 14px;
  .label-item {
    padding: 0 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    &:hover {
      background: #f6f6f6;
    }
  }
}

.dept-list-box,
.dept-detail-box {
  height: calc(100vh - 50px - 34px - 20px);
}
.dept-list-box {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  overflow: auto;
  .dept-list {
    flex-grow: 1;
  }
}
</style>
<style>
.el-select-dropdown.el-popper {
  min-height: 200px;
}
</style>
